package com.jt1078.streamserver.service;

import com.jt1078.streamserver.handler.JT1078FrameSplitter;
import com.jt1078.streamserver.handler.TalkDownHandler;
import com.jt1078.streamserver.handler.UnifiedPushHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class JT1078NettyServer implements ApplicationRunner {

    private EventLoopGroup bossGroup1;
    private EventLoopGroup workerGroup1;
    private EventLoopGroup bossGroup2;
    private EventLoopGroup workerGroup2;

    @Override
    public void run(ApplicationArguments args) {
        // 启动推流端口（视频/音频，端口6078）
        new Thread(() -> start(6078, false)).start();

        // 启动对讲端口（语音对讲，端口6080）
        new Thread(() -> start(6080, true)).start();
    }

    /**
     * 启动端口监听
     * @param port      端口号
     * @param isTalkback true=对讲端口，false=推流端口
     */
    public void start(int port, boolean isTalkback) {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        if (!isTalkback) {
            bossGroup1 = bossGroup;
            workerGroup1 = workerGroup;
        } else {
            bossGroup2 = bossGroup;
            workerGroup2 = workerGroup;
        }

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 protected void initChannel(SocketChannel ch) {
                     ChannelPipeline pipeline = ch.pipeline();
                     // JT1078 拆帧器
                     pipeline.addLast("frame", new JT1078FrameSplitter());
                     // 主推流端：音视频+G711a，支持国标推流
                     if (!isTalkback) {
                         pipeline.addLast("jt1078Push", new UnifiedPushHandler());
                     } else {
                         // 对讲端，业务处理Handler
                         pipeline.addLast("jt1078Talkback", new TalkDownHandler());
                     }
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 100)
             .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(port).sync();
            log.info("{}端口已启动，监听端口：{}", isTalkback ? "对讲" : "推流", port);
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("Netty监听端口{}异常", port, e);
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    // 优雅关闭所有端口
    public void shutdown() {
        if (bossGroup1 != null) bossGroup1.shutdownGracefully();
        if (workerGroup1 != null) workerGroup1.shutdownGracefully();
        if (bossGroup2 != null) bossGroup2.shutdownGracefully();
        if (workerGroup2 != null) workerGroup2.shutdownGracefully();
    }
}
